home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
mail
/
newmail3.000
/
newmail3
/
newmail
/
newmail.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-21
|
6KB
|
258 lines
/* newmail(1L), check for new, unread, and total mail messages */
/* Steve Creps, October 24, 1988 */
/* Last modified, July 19, 1991 */
/****************************************************************/
/* #include standard copyright notice: */
/* This program copyright Steve Creps on the above date. Do */
/* pretty much what you want with it; HOWEVER: */
/* 1) Don't accept any money for it. */
/* 2) Do leave my notices intact. */
/* 3) Do document your changes before passing it on. */
/****************************************************************/
#ifndef lint
static char ID[] = "Newmail, version 3.0, (c) 1991 Steve Creps";
#endif
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <malloc.h>
#define Fprintf (void)fprintf
#define Printf (void)printf
#define NEW 1
#define UNREAD 2
#define OLD 3
#define DEF_INTERVAL 30 /* Default sleep time between checks */
#define MIN_INTERVAL 5 /* Min must be > 0 */
#ifdef BSD
#define MAILDIR "/usr/spool/mail"
#define ENV_USER "USER"
#else
#define MAILDIR "/usr/mail"
#define ENV_USER "LOGNAME"
#endif
int optn = 0, optt = 0, optv = 1, opti = 0, optd = 0;
int optb = 0;
int ncount, ucount, tcount, old_ncount = -1;
int nextmsg(), type;
char *getenv(), *getln();
int getopt();
unsigned int sleep();
void exit();
extern int opterr, optind;
extern char *optarg;
pid_t fork(), getpid();
int
main(argc, argv)
int argc;
char *argv[];
{
char *mailfile;
int c;
FILE *mailfp;
pid_t child_id = 0;
opterr = 0;
while ((c = getopt(argc, argv, "bdi:nstv")) != EOF) {
switch (c) {
case 'b':
optb = 1;
break;
case 'd':
optd = optn = 1;
opti = DEF_INTERVAL;
break;
case 'i':
if ((opti = atoi(optarg)) < MIN_INTERVAL) {
Fprintf(stderr,
"newmail: time interval is too small\n");
exit(-1);
}
break;
case 'n':
optn = 1;
optt = 0;
break;
case 's':
optt = optv = 0;
break;
case 't':
optt = 1;
optn = optv = 0;
break;
case 'v':
optv = 1;
optt = 0;
break;
case '?':
Fprintf(stderr, "newmail: invalid option: %s\n",
argv[optind - 1]);
exit(-1);
}
}
if (argc > optind + 1) {
Fprintf(stderr, "Usage: newmail [ -b -d -i interval -n -s -t -v ] [ mailbox ]\n");
exit(-1);
}
if (optd == 0 || (child_id = fork()) == 0) {
if (optd && child_id == 0) {
Printf("newmail daemon started, pid == %d\n", getpid());
}
if (argc == optind) {
char *u = getenv(ENV_USER);
mailfile = (char *)malloc(sizeof(MAILDIR) + sizeof("/") +
sizeof(u) + 1);
(void)sprintf(mailfile, "%s/%s", MAILDIR, u);
} else {
#ifdef SYSV
mailfile = strdup(argv[optind]);
#else
/* No strdup() on Ultrix; sigh. Don't try to free this below. */
mailfile = argv[optind];
#endif
}
do {
ncount = ucount = tcount = 0;
if ((mailfp = fopen(mailfile, "r")) == NULL) {
if (errno != ENOENT || argc > optind) {
Fprintf(stderr, "newmail: cannot open %s\n",
mailfile);
return -1;
}
} else {
while (type = nextmsg(mailfp)) {
switch (type) {
case NEW:
ncount++;
case UNREAD:
ucount++;
case OLD:
tcount++;
break;
default:
continue;
}
}
}
if (ncount > old_ncount) {
if (optv) {
if (optb && ncount > 0) putchar(0x07);
if (tcount == 0) {
if (!optn) Printf("%s: no messages.\n",
mailfile);
} else {
Printf("%s: ", mailfile);
if (ncount) Printf("%d new, ", ncount);
if (ucount && ucount != ncount)
Printf("%d unread, ", ucount);
Printf("%d message%s total.\n", tcount,
tcount > 1 ? "s" : "");
}
} else if (optt)
Printf("%d\t%d\t%d\n", ncount, ucount, tcount);
}
old_ncount = ncount;
(void)fclose(mailfp);
#ifdef BSD
if (opti > 0) (void)sleep((unsigned)opti);
#else
if (opti > 0) (void)sleep((unsigned long)opti);
#endif
} while (opti > 0);
}
#ifdef SYSV
/* Just to be neat. See comment after strdup() above. */
free((void *)mailfile);
#endif
return optd > 0 ? child_id : ncount;
}
#define MAXLEN 12 /* we're discarding most of the end of the line */
static char line[MAXLEN] = NULL;
int
nextmsg(fp)
FILE *fp;
{
int mtype = NEW, past_header = 0;
while (strncmp(line, "From ", 5) != 0)
if (getln(fp, line, MAXLEN) == NULL) return 0;
do {
if (strlen(line) == 1) {
past_header++;
while (strlen(line) == 1)
(void)getln(fp, line, MAXLEN);
if (strncmp(line, "From ", 5) == 0) {
return mtype;
}
}
if (strncmp(line, "Status: O", 9) == 0) {
if (!past_header) mtype = UNREAD;
continue;
}
if (strncmp(line, "Status: RO", 10) == 0) {
if (!past_header) mtype = OLD;
continue;
}
} while (getln(fp, line, MAXLEN));
return mtype;
}
/* Read a line from given stream, return in line. If line is too */
/* long, truncate and read past next \n. Terminate with (char)0. */
char *
getln(fp, msgline, maxlen)
FILE *fp;
char msgline[];
int maxlen;
{
int i, maxc = maxlen - 2;
char c;
for (i = 0; i < maxc && (msgline[i] = getc(fp)) != '\n'; i++) {
if ((int)msgline[i] == EOF) {
msgline[0] = (char)0;
return NULL;
}
}
if (i == maxc) {
msgline[maxc++] = '\n';
msgline[maxc] = (char)0;
while ((c = getc(fp)) != '\n') {
if ((int)c == EOF) {
msgline[0] = (char)0;
return NULL;
}
}
} else {
msgline[i++] = '\n';
msgline[i] = (char)0;
}
return msgline;
}